package com.stox.ui.javafx.list.widget.menu;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TreeItem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.stox.client.ScripClient;
import com.stox.dto.AbstractModel;
import com.stox.dto.WatchList;
import com.stox.dto.intf.AbstractModelCollectionProvider;
import com.stox.ui.javafx.core.widget.LazyLoadingMenu;
import com.stox.ui.javafx.list.client.WatchListClient;
import com.stox.ui.javafx.list.view.WatchListView;

@Component("watchListMenu")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class WatchListMenu extends LazyLoadingMenu implements EventHandler<ActionEvent>{

	private static List<WatchListMenu> watchListMenus = new ArrayList<WatchListMenu>();
	
	public static List<WatchListMenu> getWatchListMenus(){
		return watchListMenus;
	}
	
	@Autowired
	private WatchListClient watchListClient;
	
	@Autowired
	private ScripClient scripClient;
	
	@Autowired
	private ApplicationContext applicationContext;
	
	private WatchList watchList;
	
	public WatchListMenu() {
		setOnAction(this);
		watchListMenus.add(this);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public void handle(ActionEvent event) {
		AbstractModelCollectionProvider<Collection<AbstractModel>> abstractModelCollectionProvider = null;
		if(null != getParentPopup() && null != getParentPopup().getOwnerNode() && getParentPopup().getOwnerNode() instanceof AbstractModelCollectionProvider){
			abstractModelCollectionProvider = (AbstractModelCollectionProvider<Collection<AbstractModel>>)getParentPopup().getOwnerNode();
		}
		
		abstractModelCollectionProvider = getabstractModelSearchableFromAcestor(this);
		
		if(null != abstractModelCollectionProvider){
			Collection<AbstractModel> abstractModels = abstractModelCollectionProvider.get();
			List<Long> codes = new LinkedList<Long>();
			for(AbstractModel abstractModel : abstractModels){
				codes.add(abstractModel.getId());
			}
			watchListClient.addToWatchList(codes, watchList.getId());
			
			if(null != WatchListView.getInstance()){
				TreeItem<AbstractModel>treeItem = WatchListView.getInstance().getWatchListTreeItemById(watchList.getId());
				if(null != treeItem) {
					List<Long> presentCodes = new ArrayList<Long>();
					for(Long id : codes){
						for(TreeItem<AbstractModel> child : treeItem.getChildren()){
							if(null != id && null != child && null != child.getValue() && null != child.getValue().getId() && child.getValue().getId().equals(id)){
								presentCodes.add(id);
								break;
							}
						}
					}
					codes.removeAll(presentCodes);
					for(Long id : codes){
						treeItem.getChildren().add(new TreeItem<AbstractModel>(scripClient.findOne(id)));
					}
					treeItem.setExpanded(true);
				}
			}
		}
		hideAllParentPopups(this);
	}
	
	private void hideAllParentPopups(Menu menu){
		if(null != menu){
			if(null != menu.getParentPopup())
				menu.getParentPopup().hide();
			if(null != menu.getParentMenu()){
				hideAllParentPopups(menu.getParentMenu());
			}
		}
	}
	
	
	@SuppressWarnings("unchecked")
	public AbstractModelCollectionProvider<Collection<AbstractModel>> getabstractModelSearchableFromAcestor(WatchListMenu watchListMenu){
		if(null != watchListMenu.getParentPopup() && watchListMenu.getParentPopup() instanceof AbstractModelCollectionProvider){
			return (AbstractModelCollectionProvider<Collection<AbstractModel>>)watchListMenu.getParentPopup();
		}else if(null != watchListMenu.getParentMenu() && watchListMenu.getParentMenu().getParentPopup() instanceof AbstractModelCollectionProvider){
			return (AbstractModelCollectionProvider<Collection<AbstractModel>>)watchListMenu.getParentMenu().getParentPopup();
		}else if(null != watchListMenu.getParentMenu() && watchListMenu.getParentMenu() instanceof WatchListMenu){
			return getabstractModelSearchableFromAcestor((WatchListMenu)watchListMenu.getParentMenu());
		}
		return null;
	}
	
	@Override
	public Collection<MenuItem> loadMenuItems() {
		List<MenuItem> menuItems = new LinkedList<MenuItem>();
		List<WatchList> watchLists = watchListClient.findByParentId(watchList.getId());
		if(null != watchLists && !watchLists.isEmpty()){
			for(WatchList watchListOne : watchLists){
				WatchListMenu watchListMenu = applicationContext.getBean("watchListMenu",WatchListMenu.class);
				watchListMenu.setWatchList(watchListOne);
				menuItems.add(watchListMenu);
			}
		}
		return menuItems;
	}
	
	public void setWatchList(WatchList watchList) {
		this.watchList = watchList;
		setText(watchList.getName());
	}
	
	public WatchList getWatchList() {
		return watchList;
	}
	
}